package com.kira.scaffoldmvc.AntiCorruptionLayer;

import java.util.HashMap;
import java.util.Map;

// 1. 外部系统（物流系统） - 我们无法控制的代码
class ExternalLogisticsSystem {
    // 外部系统的查询接口，返回格式是Map（键为外部定义的字段）
    public Map<String, Object> queryDelivery(String orderNo) {
        // 模拟查询结果（外部系统用自己的字段名和状态码）
        Map<String, Object> result = new HashMap<>();
        result.put("order_code", orderNo);
        result.put("delivery_status", "DELIVERED"); // 外部状态：已发货
        result.put("courier_name", "张三");
        result.put("tracking_no", "EXP123456789");
        return result;
    }
}

// 2. 内部系统模型 - 我们自己的代码
// 内部用的物流信息模型（字段名和类型都是内部定义的）
class DeliveryInfo {
    private String orderNumber; // 内部订单号字段
    private String status;      // 内部状态字段
    private String courier;     // 快递员姓名
    private String trackingNumber; // 物流单号

    // 构造器和getter省略
    public DeliveryInfo(String orderNumber, String status, String courier, String trackingNumber) {
        this.orderNumber = orderNumber;
        this.status = status;
        this.courier = courier;
        this.trackingNumber = trackingNumber;
    }

    public String getOrderNumber() { return orderNumber; }
    public String getStatus() { return status; }
    public String getCourier() { return courier; }
    public String getTrackingNumber() { return trackingNumber; }
}

// 3. 防腐层接口 - 定义内部系统需要的功能
interface LogisticsAcl {
    DeliveryInfo getDeliveryInfo(String orderNo);
}

// 4. 防腐层实现 - 适配外部系统
class LogisticsAclImpl implements LogisticsAcl {
    // 持有外部系统的引用，但内部业务不直接依赖
    private final ExternalLogisticsSystem externalSystem;

    public LogisticsAclImpl(ExternalLogisticsSystem externalSystem) {
        this.externalSystem = externalSystem;
    }

    @Override
    public DeliveryInfo getDeliveryInfo(String orderNo) {
        // 1. 调用外部系统接口
        Map<String, Object> externalResult = externalSystem.queryDelivery(orderNo);

        // 2. 转换外部数据格式为内部模型（核心：解决字段名差异）
        String externalStatus = (String) externalResult.get("delivery_status");
        // 转换外部状态码为内部状态描述（解决状态定义差异）
        String internalStatus = convertStatus(externalStatus);

        // 3. 返回内部系统能直接使用的模型
        return new DeliveryInfo(
            (String) externalResult.get("order_code"), // 外部字段→内部字段
            internalStatus,
            (String) externalResult.get("courier_name"),
            (String) externalResult.get("tracking_no")
        );
    }

    // 转换外部状态码为内部状态（例如：外部"DELIVERED"→内部"已发货"）
    private String convertStatus(String externalStatus) {
        Map<String, String> statusMap = new HashMap<>();
        statusMap.put("DELIVERED", "已发货");
        statusMap.put("SHIPPED", "运输中");
        statusMap.put("RECEIVED", "已签收");
        return statusMap.getOrDefault(externalStatus, "未知状态");
    }
}

// 5. 内部业务服务 - 只依赖防腐层接口，不接触外部系统
class OrderService {
    private final LogisticsAcl logisticsAcl;

    // 依赖注入防腐层接口，而非直接依赖外部系统
    public OrderService(LogisticsAcl logisticsAcl) {
        this.logisticsAcl = logisticsAcl;
    }

    public void showDeliveryStatus(String orderNo) {
        // 调用防腐层获取物流信息（完全使用内部模型）
        DeliveryInfo info = logisticsAcl.getDeliveryInfo(orderNo);
        System.out.println("订单" + info.getOrderNumber() + "的物流状态：" + info.getStatus());
        System.out.println("快递员：" + info.getCourier() + "，物流单号：" + info.getTrackingNumber());
    }
}

// 演示
public class LogisticsDemo {
    public static void main(String[] args) {
        // 初始化外部系统
        ExternalLogisticsSystem externalSystem = new ExternalLogisticsSystem();
        // 初始化防腐层（连接内部和外部）
        LogisticsAcl logisticsAcl = new LogisticsAclImpl(externalSystem);
        // 内部业务服务（只依赖防腐层）
        OrderService orderService = new OrderService(logisticsAcl);

        // 查询订单物流信息
        orderService.showDeliveryStatus("ORD-12345");
    }
}